package com.alibaba.citrus.cr.mn.order.center.facade.function.convert;

import com.alibaba.citrus.cr.common.enums.ordercenter.SalesOrderActivityTypeEnum;
import com.alibaba.citrus.cr.common.enums.ordercenter.SalesOrderReasonEnum;
import com.alibaba.citrus.cr.common.util.DateUtils;
import com.alibaba.citrus.cr.mn.order.center.common.SetOrderTag;
import com.alibaba.citrus.cr.mn.order.center.facade.function.dataobject.AtomOrderDO;
import com.alibaba.cz.base.tool.log.Log;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.TypeReference;
import com.epoch.app.crb2btradecenter.domain.order.model.Order;
import com.epoch.app.crb2btradecenter.domain.orderline.model.OrderLine;
import com.epoch.app.crb2btradecenter.enums.OrderStatus;
import com.epoch.app.mnordercenter.model.dto.SalesOrderAtomCreateLineRequest;
import com.epoch.app.mnordercenter.model.dto.SalesOrderAtomCreateRequest;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
import org.springframework.beans.BeanUtils;

import java.util.*;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

import static com.alibaba.citrus.cr.common.constant.OrderFeaturesKey.*;

/**
 * @author zhangxiaorui
 * @ClassName SalesOrderAtomCreateRequestToAtomOrderDO
 * @description: TODO
 * @date 2023/04/25 20:16
 * @version: 1.0
 */

public class SalesOrderAtomCreateRequestToAtomOrderDOConvertor {
    private static final Log log = Log.getLogger(SalesOrderAtomCreateRequestToAtomOrderDOConvertor.class);
    /**
     * 明细单行号 布进器
     **/
    private static final Integer Order_Line_Step = 10;

    public static List<AtomOrderDO> convert(List<SalesOrderAtomCreateRequest> requestList) {

        return Optional.ofNullable(requestList).orElse(Lists.newArrayList()).stream().map(request -> {
            if (Objects.isNull(request.getIsSubmit())) {
                request.setIsSubmit(Boolean.TRUE);
            }

            AtomOrderDO atomOrderDO = new AtomOrderDO();
            atomOrderDO.setOrder(convert(request));
            atomOrderDO.setOrderLines(convertOrderLine(request));
            atomOrderDO.setAutoSubmit(request.getIsSubmit());

            for (OrderLine orderLine : atomOrderDO.getOrderLines()) {
                orderLine.setCreatorId(atomOrderDO.getOrder().getCreator());
                orderLine.setCreatorName(atomOrderDO.getOrder().getCreatorName());
                orderLine.setStatus(atomOrderDO.getOrder().getStatus());
            }
            return atomOrderDO;
        }).collect(Collectors.toList());
    }

    public static Order convert(SalesOrderAtomCreateRequest request) {
        log.info("SalesOrderAtomCreateRequestToAtomOrderDOConvertor#convert request={}", JSON.toJSONString(request));
        Order order = new Order();
        BeanUtils.copyProperties(request, order);

        order.setBusinessType(StringUtils.isBlank(request.getBusinessType()) ? null : Integer.parseInt(request.getBusinessType()));
        order.setBisUnitCode(request.getBusinessUnitCode());
        order.setBisUnitName(request.getBusinessUnitName());
        order.setCreator(request.getCreatorCode());
        order.setCreatorCode(request.getCreatorCode());
        order.setCreatorName2(request.getCreatorName());
        order.setOrderType(request.getSalesOrderType());
        order.setOrderTypeName(request.getSalesOrderTypeName());
        order.setChannelCode(request.getBusinessChannel());
        order.setChannelName(request.getBusinessChannelName());
        order.setTransportModeCode(request.getDeliveryMethodCode());
        order.setTransportModeName(request.getDeliveryMethodName());
        order.setOrganizationCode(request.getSalesOrganizationCode());
        order.setOrganizationName(request.getSalesOrganizationName());
        order.setReceiveAddressCode(request.getShipToPartyCode());
        order.setReceiveDetailAddress(request.getShipToPartyName());
        order.setDepartmentName(request.getSalesDepartmentName());
        order.setDepartmentCode(request.getSalesDepartmentCode());
        order.setSaleChannelName(request.getSalesChannelName());
        order.setSaleChannelCode(request.getSalesChannelCode());
        order.setRemark(request.getNote());
        order.setCostCenter(request.getCostCenterCode());
        order.setCustomerPurchaseDate(DateUtils.string2Date(request.getCustomerPurchaseDate()));//客户采购订单日期
        order.setCustomerExpectDate(DateUtils.string2Date(request.getExpectedDeliveryDate()));//期望日期
        order.setCustomerReferenceNo(request.getCustomerPurchaseOrderNo());//客户采购订单号
        if (StringUtils.isNotBlank(request.getOrderReasonCode())) {
            order.setCreateReason(request.getOrderReasonCode());
            SalesOrderReasonEnum salesOrderReasonEnum = SalesOrderReasonEnum.of(request.getOrderReasonCode());
            if (salesOrderReasonEnum != null) {
                order.setCreateReasonName(salesOrderReasonEnum.getDesc());
            }
        }
        // 主单上保存逻辑仓，否则会导致单据推送SAP失败
        SalesOrderAtomCreateLineRequest salesOrderAtomCreateLineRequest = request.getOrderDetails().get(0);
        String shippingWarehouseCode = salesOrderAtomCreateLineRequest.getShippingWarehouseCode();
        String shippingWarehouseName = salesOrderAtomCreateLineRequest.getShippingWarehouseName();
        order.setWareHouseCode(shippingWarehouseCode);
        order.setWareHouseName(shippingWarehouseName);

        // 状态确认 默认待提交，若IS-Submit=true，则为已推送 推送SAP
        order.setStatus(BooleanUtils.isTrue(request.getIsSubmit()) ? OrderStatus.PUSHING.getCode() : OrderStatus.BEFORE_SUBMIT.getCode());
        // 当前单据都是 normal 订单
        order.setOrderTag(SetOrderTag.NORMAL);

        // 一盘货新增字段
        order.setOrderBizTag(StringUtils.join(request.getOrderBizTag(), ","));
        order.setAutoFulfillment(request.getAutoFulfillment());
        order.setFulfillmentPriority(request.getFulfillmentPriority());
        order.setFulfillmentTypeCode(request.getFulfillmentTypeCode());
        order.setReceiveWareHouseOutCode(request.getReceiveWarehouseCode());
        order.setReceiveWareHouseName(request.getReceiveWarehouseName());
        order.setReceiveFactoryCode(request.getReceiveFactoryCode());
        order.setReceiveStockCode(request.getReceiveStockCode());

        // 转换内部扩展字段
        refreshInfo4Features(order, request);
        return order;
    }

    static void refreshInfo4Features(Order order, SalesOrderAtomCreateRequest request) {
        Map<String, String> featuresMap = JSON.parseObject(order.getFeatures(), new TypeReference<Map<String, String>>() {});
        featuresMap = Optional.ofNullable(featuresMap).orElse(Maps.newHashMap());
        featuresMap.put(KA_SYSTEM, request.getKaSystem());
        featuresMap.put(KA_AREA, request.getKaArea());
        featuresMap.put(SOURCE_ORDER_TIME, request.getSourceOrderTime());
        //300订单，features存储过账仓
        if (StringUtils.isNotBlank(request.getFeatures())) {
            Map<String, String> features = JSON.parseObject(request.getFeatures(), new TypeReference<Map<String, String>>() {});
            featuresMap.putAll(features);
//            featuresMap.put("shippingWarehouseCode", features.get("shippingWarehouseCode"));
//            featuresMap.put("deliveryFactoryCode", features.get("deliveryFactoryCode"));
//            featuresMap.put("stockCode", features.get("stockCode"));
        }
        order.setFeatures(JSONObject.toJSONString(featuresMap));
    }

    public static List<OrderLine> convertOrderLine(SalesOrderAtomCreateRequest order) {
        List<SalesOrderAtomCreateLineRequest> orderDetails = order.getOrderDetails();
        if (CollectionUtils.isEmpty(orderDetails)) {
            return Collections.emptyList();
        }

        List<OrderLine> orderLineList = new ArrayList<>();
        // 原品行对应的行号
        Map<String, String> originalLineNumMap = new HashMap<>();

        // 遍历非赠品行
        AtomicReference<Integer> num = new AtomicReference<>(0);
        orderDetails.forEach(lineRequest -> {
            if (StringUtils.isNotBlank(lineRequest.getGiftFlag()) && !"X".equals(lineRequest.getGiftFlag())) {
                // 赠品行不处理
                return;
            }

            // 循环行数 递增
            num.set(num.get() + 1);
            // 记录来源行号和内部行号关系，生成赠品行时需要增加记录原品内部行号到features里
            originalLineNumMap.put(lineRequest.getSourceLineNum(), String.valueOf(num.get() * Order_Line_Step));

            orderLineList.add(buildOrderLine(order, lineRequest, String.valueOf(num.get() * Order_Line_Step)));
        });

        // 遍历赠品行
        Map<String, String> giftLineNumMap = new HashMap<>();
        orderDetails.forEach(lineRequest -> {
            if (StringUtils.isBlank(lineRequest.getGiftFlag()) || "X".equals(lineRequest.getGiftFlag()) || StringUtils.isBlank(lineRequest.getBuyItemNo())) {
                // 非赠品行不处理
                return;
            }

            String originalLineNum = originalLineNumMap.get(lineRequest.getBuyItemNo());
            String giftLineNum;
            if (StringUtils.isBlank(originalLineNum)) {
                // 拿不到原品行时，按照非赠品往上递增行号
                num.set(num.get() + 1);
                giftLineNum = String.valueOf(num.get() * Order_Line_Step);
            } else {
                // 拿原品行对应的最大赠品行号，拿不到则用原品行号
                giftLineNum = giftLineNumMap.getOrDefault(originalLineNum, originalLineNum);
                giftLineNum = String.valueOf(Integer.parseInt(giftLineNum) + 1);
                giftLineNumMap.put(originalLineNum, giftLineNum);
            }
            lineRequest.setBuyItemNo(originalLineNum); // 置换成内部行号

            orderLineList.add(buildOrderLine(order, lineRequest, giftLineNum));
        });

        return orderLineList;
    }

    private static OrderLine buildOrderLine(SalesOrderAtomCreateRequest order, SalesOrderAtomCreateLineRequest lineRequest, String num) {
        OrderLine lineSDO = new OrderLine();
        BeanUtils.copyProperties(lineRequest, lineSDO);
        // 明细单行号 当前 * 步长
        lineSDO.setSerialNumber(num);
        lineSDO.setScItemId(lineRequest.getProductCode());
        lineSDO.setScItemTitle(lineRequest.getProductName());
        lineSDO.setQuantity(Integer.parseInt(lineRequest.getProductQuantity()));
        lineSDO.setSaleUnit(lineRequest.getSalesUnitCode());
        lineSDO.setSaleUnitName(lineRequest.getSalesUnitName());
        lineSDO.setInventoryUnitCode(lineRequest.getStockUnitCode());
        lineSDO.setInventoryUnit(lineRequest.getStockUnitName());
        lineSDO.setShouldPayFee(lineRequest.getTotalAmount());// TODO 应付金额
        lineSDO.setUnitConvert(lineRequest.getUnitConversionRelationship());
        lineSDO.setProductationTime(DateUtils.string2Date(lineRequest.getProductionDate()));
        lineSDO.setRemark(lineRequest.getNote());
        lineSDO.setScItemOutCode(lineRequest.getProductCode());
        lineSDO.setTotalActivityFee(lineRequest.getActivityTotalAmount());
        lineSDO.setActivityPrice(lineRequest.getActivityPrice());
        lineSDO.setActivityCode(lineRequest.getActivityId());
        lineSDO.setActivityName(lineRequest.getActivityName());
        lineSDO.setActivityLineNo(lineRequest.getActivityLineNo());
        lineSDO.setOrderLineTag(SetOrderTag.NORMAL);
        Map<String, String> features = Maps.newHashMap();
        features.put(GIFT_FLAG, lineRequest.getGiftFlag()); // 针对用户活动打标
        if (StringUtils.isNotBlank(lineRequest.getBuyItemNo())) {
            features.put(GIFTS_MAIN_SINGLE, lineRequest.getBuyItemNo()); // 推SAP时从这里取原品行号
        }
        if (StringUtils.isNotBlank(lineRequest.getActivityType())) {
            features.put(ACTIVITY_NUMBER, lineRequest.getActivityLineNo()); // 活动项目号
            // 构造活动信息
            List<Map<String, Object>> activityDetails = buildActivityList(lineRequest);
            features.put(ACTIVITY_DETAILS, JSON.toJSONString(activityDetails)); // 活动明细信息
        }
        if (StringUtils.isNotBlank(lineRequest.getManualPrice())) {
            lineSDO.setManualPrice(lineRequest.getManualPrice());
            features.put(MANUAL_PRICE, lineRequest.getManualPrice());//手工单价
        }
        if (StringUtils.isNotBlank(lineRequest.getManualTotalAmount())) {
            features.put(MANUAL_TOTAL_AMOUNT, lineRequest.getManualTotalAmount());//手工总金额
            lineSDO.setManualTotalAmount(lineRequest.getManualTotalAmount());
        }
        if (StringUtils.isNotBlank(lineRequest.getSourceUnit())) {
            features.put(SOURCE_UNIT, lineRequest.getSourceUnit());
        }
        if (StringUtils.isNotBlank(lineRequest.getSourcePrice())) {
            features.put(SOURCE_PRICE, lineRequest.getSourcePrice());
        }
        if (StringUtils.isNotBlank(lineRequest.getSourceQuantity())) {
            features.put(SOURCE_QUANTITY, lineRequest.getSourceQuantity());
        }
        /* if (OrderCategoryEnum.GROUP.getCode().equals(order.getOrderCategoryCode()) && !Boolean.parseBoolean(order.getAutoFulfillment())) {
                features.put(FULFILLMENT_STATUS, FulfillmentStatusEnum.BEFORE_FULFILLMENT.getCode());
            } */
        if (StringUtils.isNotBlank(lineRequest.getFeatures())) {
            features.putAll(JSON.parseObject(lineRequest.getFeatures(), new TypeReference<Map<String, String>>() {}));
        }
        lineSDO.setFeatures(JSONObject.toJSONString(features));

        // 一盘货新增字段
        lineSDO.setProductationTime(DateUtils.string2Date(lineRequest.getProductionDate()));
        lineSDO.setConfirmQuantity(Objects.isNull(lineRequest.getConfirmQuantity()) ? null : Integer.parseInt(lineRequest.getConfirmQuantity()));

        return lineSDO;
    }

    private static List<Map<String, Object>> buildActivityList(SalesOrderAtomCreateLineRequest lineRequest) {
        try {
            String[] activityTypes = lineRequest.getActivityType().split("/");
            String[] activityIds = lineRequest.getActivityId().split("/");
            String[] activityLineNos = lineRequest.getActivityLineNo().split("/");

            List<Map<String, Object>> activityDetails = new ArrayList<>();
            for (int i = 0; i < activityTypes.length; i++) {
                if (StringUtils.isBlank(activityTypes[i])) {
                    continue;
                }
                Map<String, Object> activityDetail = Maps.newHashMap();
                activityDetail.put(IS_SELECT, true);
                activityDetail.put(ACTIVITY_TYPE, activityTypes[i]);
                activityDetail.put(ACTIVITY_TERM_ID, activityLineNos.length > i ? activityLineNos[i] : "");
                activityDetail.put(ACTIVITY_CODE, activityIds.length > i ? activityIds[i] : "");

                // 特价活动
                if (SalesOrderActivityTypeEnum.SPECIAL_OFFER_PRICE.getCode().equals(activityTypes[i])) {
                    // 活动价格
                    activityDetail.put(SPECIAL_OFFER_PRICE, lineRequest.getActivityTotalAmount());
                }

                activityDetails.add(activityDetail);
            }
            return activityDetails;
        } catch (Exception e) {
            log.error("SalesOrderAtomCreateRequestToAtomOrderDOConvertor#buildActivityList error", e);
        }
        return Collections.emptyList();
    }

}
